package com.zzyl.job;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.zzyl.constant.CacheConstants;
import com.zzyl.entity.AlertRule;
import com.zzyl.mapper.AlertRuleMapper;
import com.zzyl.service.AlertRuleService;
import com.zzyl.vo.DeviceDataVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @version 1.0
 * @description 告警任务
 * @package com.zzyl.job
 */
@Component
@Slf4j
public class AlertJob {

    @Resource
    private AlertRuleMapper alertRuleMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private AlertRuleService alertRuleService;

    /**
     * 每分钟执行一次
     */
    @Scheduled(cron = "0/30 * * * * ?")
    public void deviceDataAlertFilter(){
        log.info("执行告警任务开始...");
        //查询所有规则, 有效的status=0
        List<AlertRule> alertRules = alertRuleMapper.selectByFunctionId(null, null, null);
        // 是否为空  CollUtil操作集合, JSONUtil操作json字符串，BeanUtils实体对象, StrUtil操作字符串, LocalDateTimeUtil操作日期
        if(CollUtil.isEmpty(alertRules)){
            log.info("没有告警规则，不处理.");
            return;
        }

        //查询所有设备最后一次上报的数据, 每一个都是json字符串，json > List<DeviceDataVo>
        List<Object> values = stringRedisTemplate.opsForHash().values(CacheConstants.IOT_DEVICE_LAST_DATA_KEY);
        if(CollUtil.isEmpty(values)){
            log.info("没有上报数据，不处理.");
            return;
        }
        // 数据格式标准化处理
        List<DeviceDataVo> deviceDataVoList = new ArrayList<>();
        // 遍历上报的数据
        values.forEach(json->{
            String jsonString = json.toString();
            List<DeviceDataVo> deviceDataVos = JSONUtil.toList(jsonString, DeviceDataVo.class);
            deviceDataVoList.addAll(deviceDataVos);
        });

        //数据报警处理器
        deviceDataVoList.forEach(alertRuleService::alertFilter);

        log.info("执行告警任务结束...");
    }
}
